using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace Deloitte.Windows.Controls
{
	/// <summary>
	/// Summary description for ControlDataViewRowFilter.
	/// </summary>
	public class DataViewRowFilterControl : System.Windows.Forms.UserControl
	{
		private DataView myDataView;        
        private Button filterButton;
        private Button removeFilterButton;
        private DataGridView dataGridView;
        private DataGridViewComboBoxColumn columnNamesColumn;
        private DataGridViewComboBoxColumn operatorColumn;
        private DataGridViewTextBoxColumn valueColumn;
        private DataGridViewComboBoxColumn andOrColumn;
        private Button saveFilterButton;
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public DataViewRowFilterControl(DataView dv)
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();

			CommonConstructorCode();

			this.DataView = dv;	
			
					
		}
		public DataViewRowFilterControl()
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();
			
			CommonConstructorCode();					
		}
		public DataView DataView
		{
			get{return this.myDataView;}
			set
			{
				this.myDataView = value;
				this.SetColumnNames();
			}
		}
		private void CommonConstructorCode()
		{			
			     	
		}
        private void SetColumnNames()
        {
            this.columnNamesColumn.Items.Clear();
            object[] columnNames= new object[this.myDataView.Table.Columns.Count];
            int i = 0;
            foreach (DataColumn col in this.myDataView.Table.Columns)
            {
                columnNames[i] = col.ColumnName;
                i++;
            }
            this.columnNamesColumn.Items.AddRange(columnNames);
        }

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
            this.filterButton = new System.Windows.Forms.Button();
            this.removeFilterButton = new System.Windows.Forms.Button();
            this.dataGridView = new System.Windows.Forms.DataGridView();
            this.columnNamesColumn = new System.Windows.Forms.DataGridViewComboBoxColumn();
            this.operatorColumn = new System.Windows.Forms.DataGridViewComboBoxColumn();
            this.valueColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.andOrColumn = new System.Windows.Forms.DataGridViewComboBoxColumn();
            this.saveFilterButton = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
            this.SuspendLayout();
            // 
            // filterButton
            // 
            this.filterButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.filterButton.AutoSize = true;
            this.filterButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
            this.filterButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.filterButton.Location = new System.Drawing.Point(8, 153);
            this.filterButton.Name = "filterButton";
            this.filterButton.Size = new System.Drawing.Size(43, 25);
            this.filterButton.TabIndex = 30;
            this.filterButton.Text = "&Filter";
            this.filterButton.UseVisualStyleBackColor = true;
            this.filterButton.Click += new System.EventHandler(this.filterButton_Click);
            // 
            // removeFilterButton
            // 
            this.removeFilterButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.removeFilterButton.AutoSize = true;
            this.removeFilterButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
            this.removeFilterButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.removeFilterButton.Location = new System.Drawing.Point(57, 153);
            this.removeFilterButton.Name = "removeFilterButton";
            this.removeFilterButton.Size = new System.Drawing.Size(85, 25);
            this.removeFilterButton.TabIndex = 31;
            this.removeFilterButton.Text = "&Remove Filter";
            this.removeFilterButton.UseVisualStyleBackColor = true;
            this.removeFilterButton.Click += new System.EventHandler(this.removeFilterButton_Click);
            // 
            // dataGridView
            // 
            dataGridViewCellStyle1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.dataGridView.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1;
            this.dataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.columnNamesColumn,
            this.operatorColumn,
            this.valueColumn,
            this.andOrColumn});
            this.dataGridView.Location = new System.Drawing.Point(8, 8);
            this.dataGridView.Name = "dataGridView";
            this.dataGridView.Size = new System.Drawing.Size(456, 139);
            this.dataGridView.TabIndex = 32;
            // 
            // columnNamesColumn
            // 
            this.columnNamesColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
            this.columnNamesColumn.HeaderText = "Column Names";
            this.columnNamesColumn.MaxDropDownItems = 50;
            this.columnNamesColumn.Name = "columnNamesColumn";
            this.columnNamesColumn.Width = 83;
            // 
            // operatorColumn
            // 
            this.operatorColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
            this.operatorColumn.HeaderText = "Operator";
            this.operatorColumn.Items.AddRange(new object[] {
            "=",
            "<>",
            "<",
            ">",
            "<=",
            ">=",
            "LIKE",
            "NOT LIKE",
            "BETWEEN",
            "NOT BETWEEN",
            "IN",
            "NOT IN"});
            this.operatorColumn.Name = "operatorColumn";
            this.operatorColumn.Width = 57;
            // 
            // valueColumn
            // 
            this.valueColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
            this.valueColumn.HeaderText = "Value";
            this.valueColumn.Name = "valueColumn";
            this.valueColumn.Resizable = System.Windows.Forms.DataGridViewTriState.True;
            this.valueColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
            this.valueColumn.Width = 39;
            // 
            // andOrColumn
            // 
            this.andOrColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
            this.andOrColumn.HeaderText = "And/Or";
            this.andOrColumn.Items.AddRange(new object[] {
            "AND",
            "OR"});
            this.andOrColumn.Name = "andOrColumn";
            this.andOrColumn.Width = 48;
            // 
            // saveFilterButton
            // 
            this.saveFilterButton.Location = new System.Drawing.Point(157, 154);
            this.saveFilterButton.Name = "saveFilterButton";
            this.saveFilterButton.Size = new System.Drawing.Size(75, 23);
            this.saveFilterButton.TabIndex = 33;
            this.saveFilterButton.Text = "&Save Filter";
            this.saveFilterButton.UseVisualStyleBackColor = true;
            this.saveFilterButton.Click += new System.EventHandler(this.saveFilterButton_Click);
            // 
            // DataViewRowFilterControl
            // 
            this.AutoScroll = true;
            this.Controls.Add(this.saveFilterButton);
            this.Controls.Add(this.dataGridView);
            this.Controls.Add(this.removeFilterButton);
            this.Controls.Add(this.filterButton);
            this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.Name = "DataViewRowFilterControl";
            this.Size = new System.Drawing.Size(472, 181);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		#endregion
						
		private string GetFilterStatement()
		{
			DataGridViewRow dr=null;
			string myOperator, colName, andOr, myValue;
			System.Type thisDataType;
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			for(int i =0;i<this.dataGridView.Rows.Count -1;i++)
			{				
				dr = this.dataGridView.Rows[i];
                colName = dr.Cells[0].Value.ToString();
                myOperator = dr.Cells[1].Value.ToString();
                myValue = dr.Cells[2].Value.ToString();
                if (dr.Cells[3].Value != null) { andOr = dr.Cells[3].Value.ToString(); }
                else { andOr = string.Empty; }
				thisDataType = this.myDataView.Table.Columns[colName].DataType;
				if(isValidOperator(myOperator, thisDataType))
				{
					sb.Append("[" + colName + "]");
					sb.Append(" " + myOperator + " ");
					if (thisDataType == typeof(string))
					{	
						if(myOperator=="IN")sb.Append(" " + myValue + " ");
						else{sb.Append("'" + myValue + "'");}
					}
					else if(thisDataType.FullName.IndexOf("Date") != -1)
					{
						//todo: fix the between statement
						if(myOperator=="BETWEEN")sb.Append(" " + myValue + " ");
						else{sb.Append("#" + myValue + "#");}
					}
					else 
					{
						sb.Append(" " + myValue + " ");
					}															
					if(i<this.dataGridView.Rows.Count-2)sb.Append(" " + andOr + " ");
				}
				else
				{
					MessageBox.Show("Error in the filter statement");
					return null;
					//todo: display the error control with
				}
				//todo: implement filter statement logic
			}			
			return sb.ToString();//"[" + this.myDataView.Table.Columns[0].ColumnName + "] LIKE " + "'C%'";
		}
		private bool isValidOperator(string thisOperator, System.Type thisDataType)
		{
			string[] stringOps = {"=", "<>", "LIKE", "!=", "IN", "NOT LIKE", "NOT IN"};
			string[] dateOps = {"=", "<>", "BETWEEN", "NOT BETWEEN", "!="};
			string[] numOps = {"IN", "LIKE", "BETWEEN", "NOT BETWEEN"};
			//todo: code other data types here, also add an error table.  
			//we may want to add a generic error control to display errors.
			if (thisDataType==typeof(string))
			{								
				if(Array.IndexOf(stringOps, thisOperator) == -1)return false;
				else{return true;}
			}
			else if(thisDataType.FullName.IndexOf("Date") != -1)
			{
				if(Array.IndexOf(dateOps, thisOperator) == -1)return false;
				else{return true;}
			}
			else {
				if(Array.IndexOf(numOps, thisOperator) == -1)return true;
				else{return false;}
			}			               			
		}

        private void filterButton_Click(object sender, EventArgs e)
        {
            string filterStatement = null;
            try
            {
                filterStatement = GetFilterStatement();
                this.DataView.RowFilter = filterStatement;
            }
            //todo: add the evaluate exception to the error control or emial the developer
            catch (System.Data.EvaluateException exEE) { MessageBox.Show(("The expression:\n" + filterStatement + "\n could not be evaluated.\n\n" + exEE.Message)); }
            catch (System.Data.SyntaxErrorException exSEE) { MessageBox.Show(("The expression:\n" + filterStatement + "\n could not be evaluated.\n\n" + exSEE.Message)); }
            catch (Exception ex) { MessageBox.Show(ex.ToString()); }
        }

        private void removeFilterButton_Click(object sender, EventArgs e)
        {
            this.DataView.RowFilter = string.Empty;
        }

        private void saveFilterButton_Click(object sender, EventArgs e)
        {
            
        }
	}
}
